package com.wish.aio;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.AsynchronousServerSocketChannel;
import java.nio.channels.AsynchronousSocketChannel;
import java.nio.channels.CompletionHandler;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutionException;

import com.wish.common.MyUtils;


/**
 * NIO是通过多路选择器selector不断轮询读写操作来实现异步 AIO则是通过事件驱动的，真正的异步
 *
 * @author tantexian
 * @since 2016/7/7
 */
public class AIORobotServer {


    @SuppressWarnings("Since15")
    private static AsynchronousServerSocketChannel asynchronousServerSocketChannel;
    private static CountDownLatch countDownLatch;

    public static void main(String[] args) {
        final int port = args.length >= 1 ? Integer.parseInt(args[0]) : MyUtils.getDefaultPort();

        try {
            //noinspection Since15
            asynchronousServerSocketChannel = AsynchronousServerSocketChannel.open();
            // noinspection Since15
            System.out.println(port);
            asynchronousServerSocketChannel.bind(new InetSocketAddress(port));
            System.out.println("I,m a smart robot and wait for you ask. [I'm listen on port " + port + "]\n");
        }
        catch (IOException e) {
            e.printStackTrace();
        }
        new Thread(new Runnable() {
            @SuppressWarnings("Since15")
            public void run() {
                //countDownLatch = new CountDownLatch(1);
                final ByteBuffer buffer = ByteBuffer.allocate(1024);
                // 接收客户端的连接
                asynchronousServerSocketChannel.accept(this, new CompletionHandler<AsynchronousSocketChannel, Runnable>() {
                    public void completed(AsynchronousSocketChannel result, Runnable attachment) {
                        try {

                            result.read(buffer).get();
                            /**
                             * flip方法将Buffer从读写模式切换。调用flip()方法会将position设回0，并将limit设置成之前position的值。
                             * 换句话说，position现在用于标记读的位置，limit表示之前写进了多少个byte、char等 —— 现在能读取多少个byte、char等。
                             */
                            buffer.flip();
                            System.out.println(Thread.currentThread().getName() + " received message: " + new String(buffer.array()));


                            ByteBuffer writeBuffer = ByteBuffer.allocate(1024);
                            String msg = "Hello";
                            writeBuffer.put(msg.getBytes());
                            result.write(writeBuffer);
                            writeBuffer.flip();

                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        } catch (ExecutionException e) {
                            e.printStackTrace();
                        }


                        System.out.println("result == " + result + "  attachment == " + attachment);
                    }

                    public void failed(Throwable exc, Runnable attachment) {

                    }
                });
               /* try {
                    countDownLatch.await();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }*/
            }
        }).start();
    }
}
